using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace Acms.Bll
{
    public class Email : BaseItem
    {
        protected Email() : base() { }
        protected Email(Hashtable table) : base(table) { }
        protected Email(Hashtable table, List<Email> collection) : base(table, collection) { }


        protected override Acms.SqlDal.Base CreateDal()
        {
            return new Acms.SqlDal.EmailDal();
        }

        public static Email CreateInstance(User user, string filePath)
        {
            Email tmp = new Email();
            tmp.created = DateTime.Now;
            tmp.userId = user.Id;
            tmp.user = user;
            tmp.filePath = filePath;
            tmp.CreateEmail();
            return tmp;
        }

        public static Email CreateInstance(string name, string emailAddress, string filePath)
        {
            Email tmp = new Email();
            tmp.created = DateTime.Now;
            tmp.name = name;
            tmp.emailAddress = emailAddress;
            tmp.filePath = filePath;
            tmp.CreateEmail();
            return tmp;
        }

        public new void Update()
        {
            base.Update();
        }

        protected override void SaveChanges(ref object concurencyId, Acms.SqlDal.Base dal)
        {
            ((SqlDal.EmailDal)dal).Update(ref id, userId, name, emailAddress, filePath, to, subject, body, bcc, cc, from, replyTo, html, created, sent, failed, ref concurencyId);
        }

        private void LoadXmlDocument()
        {
            System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();
            xmlDocument.Load(FilePath);
            if (xmlDocument != null)
            {
                System.Xml.XmlNode subjectNode = xmlDocument.DocumentElement.SelectSingleNode("subject");
                if (subjectNode != null)
                {
                    subject = subjectNode.InnerText;
                }

                System.Xml.XmlNode bodyNode = xmlDocument.DocumentElement.SelectSingleNode("body");
                if (bodyNode != null)
                {
                    body = bodyNode.InnerText;
                }

                System.Xml.XmlNode bccNode = xmlDocument.DocumentElement.SelectSingleNode("bcc");
                if (bccNode != null)
                {
                    bcc = bccNode.InnerText;
                }

                System.Xml.XmlNode formatNode = xmlDocument.DocumentElement.SelectSingleNode("format");
                if (formatNode != null)
                {
                    if (formatNode.InnerText != null && formatNode.InnerText.ToLower() == "html")
                        html = true;
                    else
                        html = false;
                }

                System.Xml.XmlNode ccNode = xmlDocument.DocumentElement.SelectSingleNode("cc");
                if (ccNode != null)
                {
                    cc = ccNode.InnerText;
                }

                System.Xml.XmlNode fromNode = xmlDocument.DocumentElement.SelectSingleNode("from");
                if (fromNode != null)
                {
                    from = fromNode.InnerText;
                }

                System.Xml.XmlNode replyToNode = xmlDocument.DocumentElement.SelectSingleNode("replyTo");
                if (replyToNode != null)
                {
                    replyTo = replyToNode.InnerText;
                }
            }
        }

        private void CreateEmail()
        {
            LoadXmlDocument();
            if (user != null)
            {
                Format("DisplayName", user.DisplayName);
                Format("FirstName", user.FirstName);
                Format("LastName", user.LastName);
                Format("UserName", user.UserName);
            }
            else
            {
                Format("DisplayName", Name);
                Format("FirstName", Name);
                Format("LastName", "");
            }
        }

        protected override void Load(Hashtable table)
        {
            id = (int)table[SqlDal.EmailDal.Fields.Id];
            userId = (int?)table[SqlDal.EmailDal.Fields.UserId];
            name = (string)table[SqlDal.EmailDal.Fields.Name];
            emailAddress = (string)table[SqlDal.EmailDal.Fields.EmailAddress];
            filePath = (string)table[SqlDal.EmailDal.Fields.FilePath];
            to = (string)table[SqlDal.EmailDal.Fields.To];
            subject = (string)table[SqlDal.EmailDal.Fields.Subject];
            body = (string)table[SqlDal.EmailDal.Fields.Body];
            bcc = (string)table[SqlDal.EmailDal.Fields.Bcc];
            cc = (string)table[SqlDal.EmailDal.Fields.CC];
            from = (string)table[SqlDal.EmailDal.Fields.From];
            replyTo = (string)table[SqlDal.EmailDal.Fields.ReplyTo];
            html = (bool)table[SqlDal.EmailDal.Fields.Html];
            created = (DateTime)table[SqlDal.EmailDal.Fields.Created];
            sent = (DateTime)table[SqlDal.EmailDal.Fields.Sent];
            failed = (bool)table[SqlDal.EmailDal.Fields.Failed];
        }

        private int id;
        public int Id
        {
            get { return id; }
        }

        private int? userId;
        public int? UserId
        {
            get { return userId; }
        }

        private string name;
        public string Name
        {
            get { return name; }
        }

        private string emailAddress;
        public string EmailAddress
        {
            get { return emailAddress; }
        }
	
	
	
        private string filePath;
        public string FilePath
        {
            get { return filePath; }
        }

        private string to;
        public string To
        {
            get { return to; }
            set { to = value; }
        }
	

        private string body;
        public string Body
        {
            get { return body; }
        }

        private string subject;
        public string Subject
        {
            get { return subject; }
        }

        private string bcc;
        public string Bcc
        {
            get { return bcc; }
            set { bcc = value; }
        }

        private string cc;
        public string CC
        {
            get { return cc; }
            set { cc = value; }
        }

        private string from;
        public string From
        {
            get { return from; }
        }

        private string replyTo;
        public string ReplyTo
        {
            get { return replyTo; }
        }

        private bool html;
        public bool Html
        {
            get { return html; }
        }

        private DateTime created;
        public DateTime Created
        {
            get { return created; }
        }

        private DateTime sent;
        public DateTime Sent
        {
            get { return sent; }
        }

        private bool failed;
        public bool Failed
        {
            get { return failed; }
        }
	

        private User user;
        public User User
        {
            get 
            {
                if (user == null && userId.HasValue && userId.Value > 0)
                    user = User.GetById(userId.Value);
                return user; 
            }
        }


	    public void Format(string name, string value)
        {
            string key = string.Format("[[{0}]]", name);
            if(body.Contains(key))
                body = body.Replace(key, value);
            if (subject.Contains(key))
                subject = subject.Replace(key, value);
        }

        public void Send()
        {
            System.Net.Mail.MailMessage mail = new System.Net.Mail.MailMessage();
            if (User != null)
            {
                mail.To.Add(new System.Net.Mail.MailAddress(User.EmailAddress, User.DisplayName));
            }
            else
            {
                mail.To.Add(new System.Net.Mail.MailAddress(EmailAddress, Name));
            }
            AddAddresses(this.CC, mail.CC);
            AddAddresses(this.Bcc, mail.Bcc);
            if (!string.IsNullOrEmpty(this.From))
                mail.From = GetAddress(From);
            if (!string.IsNullOrEmpty(this.ReplyTo))
                mail.ReplyTo = GetAddress(From);

            mail.Subject = this.Subject;
            mail.Body = this.Body;

            try
            {
                System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();
                client.Send(mail);
                mail.Dispose();
            }
            catch
            {
                failed = true;
            }

            this.to = string.Concat(mail.To[0].Address, "," , mail.To[0].DisplayName);
            this.sent = DateTime.Now;
            this.Update();
        }

        private void AddAddresses(string addresses, System.Net.Mail.MailAddressCollection collection)
        {
            if (addresses != null)
            {
                foreach (string address in addresses.Split(';'))
                {
                    collection.Add(GetAddress(address));
                }
            }
        }

        private System.Net.Mail.MailAddress GetAddress(string address)
        {
            if (address.Contains(","))
            {
                string email = address.Substring(0, address.IndexOf(","));
                string displayName = address.Substring(address.IndexOf(",") + 1);
                return new System.Net.Mail.MailAddress(email, displayName);
            }
            else
            {
                return new System.Net.Mail.MailAddress(address);
            }
        }

        public static void SendForgottenPasswordEmail(UserSecurity user, string password)
        {
            Email tmp = Email.CreateInstance(user, System.Web.HttpContext.Current.Server.MapPath("~/Emails/ForgottenPasswordEmail.xml"));
            tmp.Format("Password", password);
            tmp.Send();
        }


        internal static void SendRegisteredEmail(UserSecurity user, string password)
        {
            Email tmp = Email.CreateInstance(user, System.Web.HttpContext.Current.Server.MapPath("~/Emails/RegisteredEmail.xml"));
            tmp.Format("Password", password);
            tmp.Send();
        }
    }
}
